{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Random Forests"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fitting the random forest is essentially identical to fitting the bagging model with one exception: we tell the decision trees to consider only a subset of the predictors at each split. The code to do this is actually written in the {doc}`decision tree </content/c5/construction>` construction section.\n",
    "\n",
    "As in the bagging model, let's import the regression tree construction and load the {doc}`tips </content/appendix/data>` dataset. This is done in the hidden code cell below. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "tags": [
     "hide-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "importing Jupyter notebook from regression_tree.ipynb\n"
     ]
    }
   ],
   "source": [
    "## Import decision trees\n",
    "import import_ipynb\n",
    "import regression_tree as rt;\n",
    "\n",
    "## Import numpy and visualization packages\n",
    "import numpy as np \n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from sklearn import datasets\n",
    "\n",
    "## Load data\n",
    "tips = sns.load_dataset('tips')\n",
    "X = np.array(tips.drop(columns = 'tip'))\n",
    "y = np.array(tips['tip'])\n",
    "\n",
    "## Train-test split\n",
    "np.random.seed(1)\n",
    "test_frac = 0.25\n",
    "test_size = int(len(y)*test_frac)\n",
    "test_idxs = np.random.choice(np.arange(len(y)), test_size, replace = False)\n",
    "X_train = np.delete(X, test_idxs, 0)\n",
    "y_train = np.delete(y, test_idxs, 0)\n",
    "X_test = X[test_idxs]\n",
    "y_test = y[test_idxs]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now build the `RandomForest` class in the same way we built the `Bagger` with one difference: we add the argument `C` which controls the number of predictors the decision trees consider at each split. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class RandomForest:\n",
    "    \n",
    "    def fit(self, X_train, y_train, B, C, max_depth = 100, min_size = 2, seed = None):\n",
    "        \n",
    "        self.X_train = X_train\n",
    "        self.N, self.D = X_train.shape\n",
    "        self.y_train = y_train\n",
    "        self.B = B\n",
    "        self.C = C\n",
    "        self.seed = seed\n",
    "        self.trees = []\n",
    "        \n",
    "        np.random.seed(seed)\n",
    "        for b in range(self.B):\n",
    "            \n",
    "            sample = np.random.choice(np.arange(self.N), size = self.N, replace = True)\n",
    "            X_train_b = X_train[sample]\n",
    "            y_train_b = y_train[sample]\n",
    "            \n",
    "            tree = rt.DecisionTreeRegressor()\n",
    "            tree.fit(X_train_b, y_train_b, max_depth = max_depth, min_size = min_size, C = C)\n",
    "            self.trees.append(tree)\n",
    "            \n",
    "        \n",
    "    def predict(self, X_test):\n",
    "        \n",
    "        y_test_hats = np.empty((len(self.trees), len(X_test)))\n",
    "        for i, tree in enumerate(self.trees):\n",
    "            y_test_hats[i] = tree.predict(X_test)\n",
    "        \n",
    "        \n",
    "        return y_test_hats.mean(0)\n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can now build a random forest and compare the observed with fitted values, as follows. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 504x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Build model\n",
    "rf = RandomForest()\n",
    "rf.fit(X_train, y_train, B = 30, C = 4, max_depth = 20, min_size = 5, seed = 123)\n",
    "y_test_hat = rf.predict(X_test)\n",
    "\n",
    "## Plot\n",
    "fig, ax = plt.subplots(figsize = (7, 5))\n",
    "sns.scatterplot(y_test, y_test_hat)\n",
    "ax.set(xlabel = r'$y$', ylabel = r'$\\hat{y}$', title = r'Random Forest Observed vs. Fitted Values')\n",
    "sns.despine()"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Edit Metadata",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
